﻿/******************************************************************************
 * 【本类功能概述】                                 					      *
 *  版权所有（C）2017-                                           *
 *  保留所有权利。                                                            *
 ******************************************************************************
 *  作者 : <hughjk>
 *  创建时间:2020年3月2日 14:11:51
 *  文件描述:编辑器工具类
 *****************************************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UIElements;
using Util;
using Object = UnityEngine.Object;

namespace UtilEditors
{
    public static class UtilEditor
    {


        public static void 收Scene()
        {
            EditorApplication.ExecuteMenuItem("Window/General/Hierarchy");
            var hw = EditorWindow.focusedWindow;
            var eif = hw.GetType().GetMethod("SetExpandedRecursive");

            if (SceneManager.sceneCount > 0)
            {
                for (int i = 0; i < SceneManager.sceneCount; i++)
                {
                    Scene scene = SceneManager.GetSceneAt(i);
                    foreach (var root in scene.GetRootGameObjects())
                    {
                        eif.Invoke(hw, new object[] { root.GetInstanceID(), false });
                    }
                }
            }
        }
        [MenuItem("Tools/辅助/全部展开组件... %#&m")]
        public static void 展开组件()
        {
            var type = typeof(EditorWindow).Assembly.GetType("UnityEditor.InspectorWindow");
            var window = EditorWindow.GetWindow(type);
            FieldInfo info = type.GetField("m_Tracker", BindingFlags.NonPublic | BindingFlags.Instance);
            ActiveEditorTracker tracker = info.GetValue(window) as ActiveEditorTracker;
            for (int i = 0; i < tracker.activeEditors.Length; i++)
            {
                //这里1就是展开，0就是合起来  
                tracker.SetVisible(i, 1);
                //}  
            }
        }
        [MenuItem("Tools/辅助/全部收起组件... %#&n")]
        public static void 收起组件()
        {
            var type = typeof(EditorWindow).Assembly.GetType("UnityEditor.InspectorWindow");
            var window = EditorWindow.GetWindow(type);
            FieldInfo info = type.GetField("m_Tracker", BindingFlags.NonPublic | BindingFlags.Instance);
            ActiveEditorTracker tracker = info.GetValue(window) as ActiveEditorTracker;

            for (int i = 0; i < tracker.activeEditors.Length; i++)
            {
                //这里1就是展开，0就是合起来  
                tracker.SetVisible(i, 0);
            }
        }
        //收Assembly
        public static void SetProjectBrowserFoldersCollapsed()
        {
            var assembly = Assembly.GetAssembly(typeof(UnityEditor.Editor));
            var type = assembly.GetType("UnityEditor.ProjectBrowser");

            if (type == null)
                return;

            var browserField = type.GetField("s_LastInteractedProjectBrowser", BindingFlags.Public | BindingFlags.Static);
            var browser = browserField.GetValue(null);

            if (browser == null)
                return;

            // 确定窗口模式是否是单列
            var modeField = type.GetField("m_ViewMode", BindingFlags.NonPublic | BindingFlags.Instance);
            bool isOne = (int)modeField.GetValue(browser) == 0;

            // 获取文件夹树
            var treeField = type.GetField(isOne ? "m_AssetTree" : "m_FolderTree", BindingFlags.NonPublic | BindingFlags.Instance);
            var tree = treeField.GetValue(browser);

            var dataProperty = treeField.FieldType.GetProperty("data", BindingFlags.Instance | BindingFlags.Public);
            var data = dataProperty.GetValue(tree, null);

            var getRowsMethod = dataProperty.PropertyType.GetMethod("GetRows", BindingFlags.Instance | BindingFlags.Public);
            var setExpandedMethods = dataProperty.PropertyType.GetMethods(BindingFlags.Instance | BindingFlags.Public).ToList().FindAll(method => method.Name == "SetExpanded");
            var setExpandedMethod = setExpandedMethods[0];

            var rows = (IEnumerable)getRowsMethod.Invoke(data, null);
            bool first = true;
            // 遍历当前的行将其折叠
            foreach (var obj in rows)
            {
                if (first && !isOne)
                {
                    var itemType = obj.GetType();
                    var nameField = itemType.GetField("m_DisplayName", BindingFlags.Instance | BindingFlags.NonPublic);
                    if (nameField != null)
                    {
                        string name = (string)nameField.GetValue(obj);

                        if (name == "Assets")
                        {
                            first = false;
                            setExpandedMethod.Invoke(data, new object[] { obj, true });
                            continue;
                        }
                    }
                }
                setExpandedMethod.Invoke(data, new object[] { obj, false });
            }
            AssetDatabase.Refresh();
        }

        //获取当前场景全部节点
        public static bool FindAllObj(this Scene scene, Func<Transform, bool> every)
        {
            List<GameObject> sceneRoot = new List<GameObject>();
            //得到场景的根节点 
            scene.GetRootGameObjects(sceneRoot);
            List<Transform> AllNodel = new List<Transform>();
            for (int i = 0; i < sceneRoot.Count; i++)
            {
                AllNodel.Add(sceneRoot[i].transform);
            }
            int MaxScenNum = AllNodel.Count;
            EditorUtility.DisplayCancelableProgressBar("", "开始..", 0);
            while (sceneRoot.Count > 0)
            {
                var cur = sceneRoot[0].transform;
                bool isover = every.Invoke(cur);
                float si = (float)AllNodel.LastIndexOf(cur) / AllNodel.Count;
                bool isCancle = EditorUtility.DisplayCancelableProgressBar(scene.name, cur.name, si);
                if (isCancle || isover)
                {
                    EditorUtility.ClearProgressBar();
                    //保存
                    EditorSceneManager.SaveScene(scene);
                    //关闭
                    //EditorSceneManager.CloseScene(Scene, true);
                    return true;
                }

                sceneRoot.RemoveAt(0);
                for (int i = 0; i < cur.childCount; i++)
                {
                    var cn = cur.GetChild(i);
                    AllNodel.Add(cn);
                    sceneRoot.Add(cn.gameObject);
                }
            }
            EditorUtility.ClearProgressBar();
            return false;
        }

        public static GameObject LoadPrefabContents(string assetPath)
        {
#if DEVELOPMENT_BUILD || UNITY_EDITOR

            return PrefabUtility.LoadPrefabContents(assetPath);
#endif
            return null;
        }
        //当前场景对象全节点遍历
        public static void ScnenAllFind(Func<Transform, bool> every)
        {
            var Scene = SceneManager.GetActiveScene();
            Scene.FindAllObj(every);
        }
        //当前打开的全部场景对象全节点遍历
        public static void AllScnenAllFind(Func<Transform, bool> every)
        {
            for (int i = 0; i < SceneManager.sceneCount; i++)
            {
                var Scene = SceneManager.GetSceneAt(i);
                if (Scene.FindAllObj(every))
                {
                    return;
                }

            }
        }

        //查询路径下全部文件 
        public static void FindPathAllFile<T>(string fullPath, ref List<T> All) where T : Object
        {
            All.Clear();
            // string fullPath = "Assets/Models/21/21000001/";  //路径 
            //获取指定路径下面的所有资源文件  
            if (Directory.Exists(fullPath))
            {
                DirectoryInfo direction = new DirectoryInfo(fullPath);
                FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
                //Debug.Log(files.Length); 
                for (int i = 0; i < files.Length; i++)
                {
                    if (files[i].Name.EndsWith(".meta"))
                    {
                        continue;
                    }
                    string npath = files[i].FullName.toUintyPath();
                    T mObj = AssetDatabase.LoadAssetAtPath<T>(npath);
                    if (mObj)
                    {
                        All.Add(mObj);
                    }
                    //Debug.Log("Name:" + files[i].Name);  //打印出来这个文件架下的所有文件
                    //Debug.Log( "FullName:" + files[i].FullName );  
                    //Debug.Log( "DirectoryName:" + files[i].DirectoryName );  
                }
            }
        }

        //显示
        public static void Display(this VisualElement v, bool show)
        {
            if (show)
            {
                v.style.display = DisplayStyle.Flex;
            }
            else
            {
                v.style.display = DisplayStyle.None;
            }
        }
    }


}
